package com.yax.yapi.mainmethod;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.yax.yapi.http.OkHttpUtil;
import com.yax.yapi.plug.PlugIntf;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.stage.Stage;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.logging.Logger;

public class YapiUtil {
    private static Logger log = Logger.getLogger("YapiUtil");
   private static String yapiUrl="http://yapi.cnzhonglunnet.com";
    private static String exepath=System.getProperty("exe.path");
    private static String exeAddress=System.getProperty("exe4j.moduleName");

    public static String getExepath() {
        return exepath;
    }

    public static String getYapiUrl() {
        return yapiUrl;
    }

    public static void setYapiUrl(String yapiUrl) {
        YapiUtil.yapiUrl = yapiUrl;
    }

    public static JSONObject addYapi(String username, String cookie, String project, String menu, String path, String title, String resBody, List<Map<String,Object>> queryMapList,String markdown){
            Map map = new HashMap();
            map.put("catid", menu);
            map.put("project_id", project);
            map.put("req_body_is_json_schema", true);
            map.put("res_body_is_json_schema", true);
            map.put("res_body_type", "json");
            map.put("edit_uid", 0);
            map.put("status", "undone");
            map.put("type", "static");
            map.put("method", "GET");
            map.put("desc","<p>"+markdown+"</p>");
            map.put("markdown",markdown);
            map.put("switch_notice",true);
            map.put("path", path.contains("/")?path:"/" + path + "/1.0.0/action");
            map.put("title", title);
            map.put("req_query", queryMapList);
            map.put("username", username);
            if(resBody!=null&&!"".equals(resBody)) {
                String jsonSchema = jsonTojsonSchema(resBody);
                map.put("res_body", jsonSchema);
            }
            return createApi(cookie, map);
   }
   public static JSONObject transferYapi(Map<String, Object> componentMap,PlugIntf plugIntf,String cookie, String project_id, String catid, String id, boolean isUpdate, String newPath, Properties prop){
        JSONObject jsonObject=getApi(cookie,id);
       JSONObject data=jsonObject.getJSONObject("data");
       if(plugIntf==null) {
           String method = data.getString("method");
           if ("POST".equals(method)) {
               data.put("method", "GET");
               String req_body_other = data.getString("req_body_other");
               JSONObject reqBodyJson = JSONObject.parseObject(req_body_other, Feature.OrderedField);
               JSONObject properties = reqBodyJson.getJSONObject("properties");
               JSONArray jsonArray = reqBodyJson.getJSONArray("required");
               List<String> required = JSONArray.parseArray(jsonArray.toString(), String.class);
               List<Map<String, Object>> req_query = new ArrayList<>();
               for (String name : properties.keySet()) {
                   Map<String, Object> map = new HashMap<>();
                   map.put("name", name);
                   JSONObject property = properties.getJSONObject(name);
                   String description = property.getString("description");
                   map.put("desc", description);
                   map.put("required", required.contains(name) ? "1" : "0");
                   map.put("example", "");
                   req_query.add(map);
               }
               data.put("req_query", req_query);
               data.remove("req_body_other");
               data.put("req_headers", new ArrayList<>());
               data.remove("req_body_type");
           }
           String path = data.getString("path");
           data.put("path", path);
           if (newPath != null && !"".equals(newPath)) {
               data.put("path", newPath);
           }
           String updatePath = prop.getProperty(path);
           if (isUpdate && updatePath != null && !"".equals(updatePath)) {
               data.put("path", updatePath);
           }
           data.put("catid", catid);
           data.put("project_id", project_id);
       }else{
           plugIntf.apiTransformation(data,componentMap,isUpdate, newPath, prop,project_id, catid, id);
       }
       return saveApi(cookie,data);
        //return transferYapiT(cookie,project_id,catid,id);
    }

    public static  Map<String,String> loginYapi(String email,String password){
        HashMap<String, String > param=new HashMap<>();
        param.put("email",email);
        param.put("password",password);
        Map<String,String> result=OkHttpUtil.postForCookie(yapiUrl+"/api/user/login",param);
        return result;
    }
   public static JSONObject listGroup(String cookie){
        return JSONObject.parseObject(OkHttpUtil.get(yapiUrl+"/api/group/list",cookie,null));
   }
   public static JSONObject listProject(String cookie,String group_id){
       HashMap<String, String > param=new HashMap<>();
       param.put("group_id",group_id);
       return JSONObject.parseObject(OkHttpUtil.get(yapiUrl+"/api/project/list",cookie,param));
    }
    public static JSONObject listMenu(String cookie,String project_id){
        HashMap<String, String > param=new HashMap<>();
        param.put("project_id",project_id);
        return JSONObject.parseObject(OkHttpUtil.get(yapiUrl+"/api/interface/list_menu",cookie,param));
    }
    public static JSONObject listCat(String cookie,String cat_id){
        HashMap<String, String > param=new HashMap<>();
        param.put("catid",cat_id);
        param.put("page","1");
        param.put("limit","1000");
        return JSONObject.parseObject(OkHttpUtil.get(yapiUrl+"/api/interface/list_cat",cookie,param));
    }
    public static JSONObject getApi(String cookie,String id){
        HashMap<String, String > param=new HashMap<>();
        param.put("id",id);
        return JSONObject.parseObject(OkHttpUtil.get(yapiUrl+"/api/interface/get",cookie,param));
    }
    public static JSONObject transferYapiT(String cookie,String project_id,String catid,String id){
        Map<String,Object> param=new HashMap<>();
        param.put("project_id",project_id);
        param.put("catid",catid);
        param.put("id",id);
    return JSONObject.parseObject(OkHttpUtil.postJSON(yapiUrl+"/api/interface/up",cookie,param));
    }
    public static JSONObject createApi(String cookie,Map param){
        String response=OkHttpUtil.postJSON(yapiUrl+"/api/interface/add",cookie,param);
      return  JSONObject.parseObject(response);
    }
    public static JSONObject saveApi(String cookie,Map param){
        String response=OkHttpUtil.postJSON(yapiUrl+"/api/interface/save",cookie,param);
        return  JSONObject.parseObject(response);
    }
    public static JSONObject updateApi(String cookie,Map param){
        String response=OkHttpUtil.postJSON(yapiUrl+"/api/interface/up",cookie,param);
        return  JSONObject.parseObject(response);
    }
    public  static String jsonTojsonSchema(String json){
        JSONObject jsonObject=JSONObject.parseObject(json, Feature.OrderedField);
        if(jsonObject!=null){ jsonObject.put("success","1"); }
        recursion(jsonObject);
        JSONObject result=new JSONObject();
        result.put("$schema","http://json-schema.org/draft-04/schema#");
        result.put("type","object");
        result.put("properties",jsonObject);
        return result.toString();
    }
    public static void recursion(JSONObject jsonObject){
        Map<String,String> keyValueMap=Form.getKeyValueMap();
        Set<Map.Entry<String, Object>> set=jsonObject.entrySet();
        Iterator<Map.Entry<String, Object>> iterator=set.iterator();
        while(iterator.hasNext()){
            Map.Entry<String, Object> entry=iterator.next();
            String key= entry.getKey();
            Object value=entry.getValue();
            if(value instanceof JSONObject){
                JSONObject temp=new JSONObject();
                temp.put("type","object");
                temp.put("properties",value);
                jsonObject.put(key,temp);
                recursion((JSONObject) value);
                continue;
            }
            if(value instanceof List){
                JSONObject temp=new JSONObject();
                JSONObject itemTemp=new JSONObject();
                List<JSONObject> tempList= (List<JSONObject>) value;
                JSONObject json=tempList.get(0);
                temp.put("type","array");
                itemTemp.put("type","object");
                itemTemp.put("properties",json);
                temp.put("items",itemTemp);
                jsonObject.put(key,temp);
                recursion(json);
                continue;
            }
            if(value instanceof Integer){
                JSONObject temp=new JSONObject();
                temp.put("type","integer");
                temp.put("description",value);
                jsonObject.put(key,temp);
                String valueTemp=keyValueMap.get(key);
                if(valueTemp!=null&&!"".equals(valueTemp)){
                    temp.put("description",valueTemp);
                }
                continue;
            }
            if(value instanceof String){
                JSONObject temp=new JSONObject();
                temp.put("type","string");
                temp.put("description",value);
                jsonObject.put(key,temp);
                String valueTemp=keyValueMap.get(key);
                if(valueTemp!=null&&!"".equals(valueTemp)){
                    temp.put("description",valueTemp);
                }
                continue;
            }
            if(value instanceof Number){
                JSONObject temp=new JSONObject();
                temp.put("type","number");
                temp.put("description",value);
                jsonObject.put(key,temp);
                String valueTemp=keyValueMap.get(key);
                if(valueTemp!=null&&!"".equals(valueTemp)){
                    temp.put("description",valueTemp);
                }
                continue;
            }
            if(value instanceof Boolean){
                JSONObject temp=new JSONObject();
                temp.put("type","boolean");
                temp.put("description",value);
                jsonObject.put(key,temp);
                String valueTemp=keyValueMap.get(key);
                if(valueTemp!=null&&!"".equals(valueTemp)){
                    temp.put("description",valueTemp);
                }
                continue;
            }
        }
    }
    private  static Map<String,String> result=new HashMap<>();
    public static Map<String,String> analysis(String source){
        result.clear();
        source=source.replace("comment","COMMENT");
        int index=0;
        while(index>=0){
            index=source.indexOf("COMMENT",index);
            if(index>=0){
                getKeyValue(source,index);
                index+=8;
            }
        }
        return result;
    }
    public static void getKeyValue(String source,int index){
        int length=source.length();
        int start=-1;
        int end=-1;
        for(int i=index+8;i<length;i++){
            char ch=source.charAt(i);
            if('\''==ch){
                if(start==-1) {
                    start = i;
                    continue;
                }
                end=i;
                break;
            }
        }
        if(end+1<length&&source.charAt(end+1)==';'){
           return;
        }
        String value=source.substring(start+1,end);
        end=-1;
        for(int i=index-1;i>=0;i--){
            char ch=source.charAt(i);
            if('`'==ch){
                if(end==-1) {
                    end = i;
                    continue;
                }
                start=i;
                break;
            }
        }
        String key=source.substring(start+1,end);
        result.put(key,value);
    }
    public static String getVersion(){
        try {
            String res = OkHttpUtil.post("http://120.92.153.28:8080/gitlog/yapi/version", "", null);
            log.info("版本信息 " + res);
            JSONObject jsonObject = JSONObject.parseObject(res);
            String newVersion = jsonObject.getString("data");
            return newVersion;
        }catch (Exception e){
            e.printStackTrace();
            return "0";
        }
    }
   public static void downloadYapi(ProgressBar pb, ProgressIndicator pin,String version, String newVersion,Stage primaryStage){
        String downLoad=System.getProperty("user.dir");
        String fileName="yapi-"+newVersion+".exe";
        //String oldFileName="yapi-"+version+".exe";
        String exepath=System.getProperty("exe.path");
        log.info("当前下载路径:"+downLoad+"文件名:"+fileName +"exe路径:"+exepath);
        OkHttpUtil.download("http://120.92.153.28:8080/gitlog/yapi/downLoad",downLoad,fileName,new OkHttpUtil.OnDownloadListener(){

            @Override
            public void onDownloadSuccess(File file) {
                Thread thread =new Thread(()->{
                    try {
                        Runtime.getRuntime().exec(downLoad+"\\"+fileName+" "+exeAddress);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    System.exit(0);
                });
                thread.start();
            }

            @Override
            public void onDownloading(int progress) {
                Platform.runLater(() -> {
                pb.setProgress(progress/100d);
                pin.setProgress(progress/100d);
                });
            }

            @Override
            public void onDownloadFailed(Exception e) {
                Platform.runLater(() -> {
                Alert alert = new Alert(Alert.AlertType.ERROR);
                alert.setTitle("异常");
                alert.setHeaderText("下载错误");
                alert.setContentText("下载出错!");
                });
            }
        });
   }

}
